package vn.com.bookstore.utils;

import java.util.List;

import org.springframework.jdbc.core.RowMapper;

import vn.com.bookstore.dao.BaseDao;
import vn.com.bookstore.domain.model.PagingInfo;
import vn.com.bookstore.domain.model.SearchResult;

public abstract class DaoHelper<E> extends BaseDao{
	
	private final Integer OFFSET = 10;
	private final Integer PAGE_INDEX = 1;
	private int totalItems;
	private SearchResult<E> searchResult;
	
	public DaoHelper() {
		this.searchResult = new SearchResult<E>();
	}

	/**
	 * Return id of record has been inserted
	 * @param sql
	 * @param parameters
	 * @return
	 */
	public int insert(String sql, Object[] parameters){
		getJdbcTemplate().update(sql, parameters);
		return getJdbcTemplate().queryForInt("SELECT last_insert_id()");
	}
	
	public void delete (String sql, Object[] parameters){
		getJdbcTemplate().update(sql, parameters);
	}
	
	/**
	 * Query select with paging 
	 * @param sql
	 * @param rowMapper
	 * @param pagingInfo
	 * @return
	 */
	public SearchResult<E> queryPaging(String sql, Object[] parameters, RowMapper<Object> rowMapper, PagingInfo pagingInfo){
		if(pagingInfo == null){
			pagingInfo = initDefaultPaging();
		}
		getTotalRecords(sql, parameters);
		searchResult.setPagingInfo(pagingInfo);
		searchResult.getPagingInfo().setTotalItems(totalItems);
		searchResult.setSearchResult(getListResult(sql, parameters, rowMapper, computePageIndex(pagingInfo), pagingInfo.getOffset()));
		return searchResult;
	}
	
	@SuppressWarnings("unchecked")
	public SearchResult<E> query(String sql, Object[] parameters, RowMapper<Object> rowMapper) {
		if(parameters != null){
			searchResult.setSearchResult((List<E>) getJdbcTemplate().query(sql, parameters, rowMapper));
		} else {
			searchResult.setSearchResult((List<E>) getJdbcTemplate().query(sql, rowMapper));
		}
		return searchResult;
	}
	
	
	@SuppressWarnings("unchecked")
	public List<E> getListResult(String sql, Object[] parameters, RowMapper<Object> rowMapper, int pageIndex, int offset){
		StringBuilder sqlPaging = new StringBuilder();
		sqlPaging.append("SELECT * FROM (").append(sql).append(") AS A LIMIT ");
		sqlPaging.append(pageIndex).append(", ").append(offset);
		if(parameters == null){
			return  (List<E>) getJdbcTemplate().query(sqlPaging.toString(), rowMapper);
		}
		return ((List<E>) getJdbcTemplate().query(sqlPaging.toString(), parameters, rowMapper));
	}
	
	/**
	 * get Total records
	 * @param sql
	 */
	public void getTotalRecords(String sql, Object[] parameters){
		StringBuilder countItemSql = new StringBuilder();
		countItemSql.append("SELECT count(A.id) FROM (").append(sql).append(") as A");
		if(parameters != null){
			this.setTotalItems(getJdbcTemplate().queryForInt(countItemSql.toString(), parameters));
		} else {
			this.setTotalItems(getJdbcTemplate().queryForInt(countItemSql.toString()));
		}
	}
	
	/**
	 * Compute current index of page
	 * @param pagingInfo
	 * @return
	 */
	public int computePageIndex(PagingInfo pagingInfo){
		return ((pagingInfo.getPageIndex() - 1) * pagingInfo.getOffset()); 
	}
	
	/**
	 * Initialize PagingInfo if paging null
	 * @return
	 */
	public PagingInfo initDefaultPaging(){
		return new PagingInfo(OFFSET, PAGE_INDEX);
	}
	
	public int getIdByAccountType(String accountType){
		String sql = "SELECT id FROM account_type WHERE name = ?";
		Object[] params = new Object[]{accountType};
		return getJdbcTemplate().queryForInt(sql, params);
	}
	/*
	 * SETTERS AND GETTERS
	 */
	public int getTotalItems() {
		return totalItems;
	}


	public void setTotalItems(int totalItems) {
		this.totalItems = totalItems;
	}
	
	
}
